#pragma once
#include <iostream>
#include "socket.hpp"
#include "InetAddr.hpp"
#include "handler_connection.hpp"
//此文件功能：接受链接请求，并创建套接字
using namespace socket_ns;
class listener
{
public:
    listener(int port, handler_connection &hc)
        : _port(port),
          _listensock(std::make_unique<tcp_socket>()),
          _hc(hc)
    {
        InetAddr addr("0", _port);
        _listensock->build_server_socket(addr);//启动服务端
    }
    //接受listen套接字连接请求
    void _accepter(connection *con)
    {
        while (true)
        {
            InetAddr clientaddr;
            int code = 0;
            int sockfd = _listensock->accepter(&clientaddr, &code); // code错误信息
            if (sockfd >= 0)                                        // 接受请求成功
            {
                // TODO
                //将每个套接字看做一个connection连接
                con->_r->add_connection(sockfd,
                                        EPOLLIN | EPOLLET,
                                        std::bind(&handler_connection::handler_recv, &_hc, std::placeholders::_1),
                                        std::bind(&handler_connection::handler_send, &_hc, std::placeholders::_1),
                                        std::bind(&handler_connection::handler_excpter, &_hc, std::placeholders::_1)
                );
            }
            else
            {
                if(code == EWOULDBLOCK || code == EAGAIN)//eagain 错误表示资源不可用
                {
                    LOG(DEBUG,"accepter all link\n");
                    break;
                }
                else if(code == EINTR)//eintr 错误表示调用被一个信号中断
                {
                    LOG(DEBUG,"accepter interrupt by signal!\n");
                    continue;
                }
                else
                {
                    LOG(WARNING,"accept error\n");
                    break;
                }
            }
        }
    }
    int sockfd()
    {
        return _listensock->SockFd();
    }
    ~listener()
    {
        _listensock->close_sockfd();
    }

private:
    uint16_t _port;
    std::unique_ptr<mysocket> _listensock;
    handler_connection &_hc;
};
